#!/usr/bin/python
# -*- coding: utf-8 -*-
# @version        : 1.0
# @Create Time    : 2024/9/6 11:11
# @File           : vendor
# @IDE            : PyCharm
# @desc           : 描述

from typing import List, Optional, Union
from pydantic import BaseModel, ConfigDict, Field, computed_field
from core.data_types import DatetimeStr
from enum import Enum
from apps.check.female.schemas import QARFemaleContent, QARContentTypeEnum, QARFemaleFeature, QARFemaleOut


class QARFormStatusEnum(Enum):
    publish = '已发布'
    inspect = '检验中'
    order = '委托中'
    finish = '检验完成'
    archive = '归档'


class QAR(BaseModel):
    qar_no: Optional[str] = None
    asr_no: Optional[str] = None
    pclr_no: Optional[str] = None
    ndt_no: Optional[str] = None

    question_no: Optional[str] = None
    question_status: Optional[str] = None
    frr_no: Optional[str] = None
    correct_no: Optional[str] = None

    form_type: Optional[str] = None
    status: Optional[str] = None

    purchase_order: Optional[str] = None
    flight: Optional[str] = None
    quantity_weight: Optional[Union[str, int]] = None
    vendor: Optional[str] = None

    manufacturer: Optional[str] = None

    product_type: Optional[str] = None
    
    part_type: Optional[str] = None
    part_no: Optional[str] = None
    part_name: Optional[str] = None
    material_no: Optional[str] = None

    rev_letter: Optional[str] = None
    temper: Optional[str] = None
    zpm_cpm: Optional[str] = None
    typing: Optional[str] = None
    classing: Optional[str] = None
    grade: Optional[str] = None
    form: Optional[str] = None
    size: Optional[str] = None
    color: Optional[str] = None
    material_type: Optional[str] = None

    spec_stan: Optional[str] = None
    spec_stan_rev: Optional[str] = None
    # product_type: Optional[str] = None
    # material: Optional[str] = None

    mat_code: Optional[str] = None
    test_items: Optional[str] = None
    required_dimension: Optional[str] = None
    pclr_quantity: Optional[Union[str, int]] = None
    pclr_size: Optional[str] = None

    plan_remark: Optional[str] = None
    life_limit_req: Optional[str] = None
    life_limit_period: Optional[str] = None
    life_limit_manage: Optional[str] = None
    life_limit_date: Optional[DatetimeStr] = None

    special_property: Optional[str] = None
    manufacturer: Optional[str] = None
    change_no: Optional[str] = None
    draw_no: Optional[str] = None
    draw_no_rev: Optional[str] = None
    software_code: Optional[str] = None
    software_rev: Optional[str] = None

    atp_no: Optional[str] = None
    atp_rev: Optional[str] = None

    insp_remark: Optional[str] = None
    act_measurement: Optional[str] = None
    
    product_information: Optional[str] = None
    product_no: Optional[str] = None
    product_name: Optional[str] = None
    product_msn: Optional[str] = None

    serial_no: Optional[str] = None
    lot_batch_no: Optional[str] = None
    act_part_rev: Optional[str] = None
    act_change_no: Optional[str] = None

    act_draw_no: Optional[str] = None
    act_draw_no_rev: Optional[str] = None
    act_software_code: Optional[str] = None
    act_software_rev: Optional[str] = None
    act_atp_no: Optional[str] = None
    act_atp_rev: Optional[str] = None

    actual_weight: Optional[str] = None
    source_of_weight: Optional[str] = None
    acceptable_quant: Optional[str] = None
    rejective_quant: Optional[str] = None
    conformity_rate: Optional[str] = None

    prepared_by: Optional[str] = None
    # prepared_datetime: Optional[DatetimeStr] = None
    
    inspected_by: Optional[str] = None
    # inspected_datetime: Optional[DatetimeStr] = None

    ok_to_file: Optional[str] = None
    changes: Optional[str] = None
    attachment: Optional[str] = None

    splited_by: Optional[str] = None
    # splited_datetime: Optional[DatetimeStr] = None

    is_insp: Optional[bool] = None
    is_test: Optional[bool] = None
    is_sampling: Optional[bool] = None
    is_life_limit: Optional[bool] = None
    is_correct_order: Optional[bool] = None

    create_user: Optional[str] = None


class QARSimpleOut(QAR):
    model_config = ConfigDict(from_attributes=True)

    id: int

    update_datetime: DatetimeStr
    create_datetime: DatetimeStr


class QARASRForm(BaseModel):
    asr_no: str
    status: str
    create_datetime: DatetimeStr
    update_datetime: DatetimeStr


class QAROrderForm(BaseModel):
    order_type: Optional[str] = None
    order_no: Optional[str] = None
    status: Optional[str] = None
    create_datetime: Optional[DatetimeStr] = None
    update_datetime: Optional[DatetimeStr] = None


class QARTestContent(QAROrderForm):
    project: str
    detail_value: Optional[Union[str, List]] = []


project_match_order = {
     "NDT": "NDT",
     "MAT": "PCLR"
}


class QARContent(QARFemaleContent):
    insp_stamp: Optional[str] = None


class QAROut(QARSimpleOut):
    model_config = ConfigDict(from_attributes=True)

    contents: List[QARContent] = []
    asr_forms: Optional[List[QARASRForm]] = []
    order_forms: Optional[List[QAROrderForm]] = Field([], exclude=True)

    def match_form(self, content: QARFemaleContent):
        for key, value in project_match_order.items():
            if key in content.project:
                form = [i for i in self.order_forms if i.order_type == value]
                return form[0] if form else None
        return None

    @computed_field
    def test_contents(self) -> List[QARTestContent]:
        items = []
        for content in self.contents:
            if content.content_type != QARContentTypeEnum.test.value:
                continue
            form = self.match_form(content=content)
            if form:
                item = QARTestContent(
                    project=content.project,
                    detail_value=content.detail_value,
                    **form.model_dump()
                )
            else:
                item = QARTestContent(
                    project=content.project,
                    detail_value=content.detail_value
                )
            items.append(item)
        return items


class QARIn(QAR):
    model_config = ConfigDict(from_attributes=True)

    female_contents: List[QARFemaleContent] = Field([], exclude=True)
    asr_features : List[QARFemaleFeature] = Field([], exclude=True)
    contents: List[QARFemaleContent] = []

    def update(self, data) -> QAR:
        for key, value in QARFemaleOut.model_validate(data).model_dump().items():
            if not hasattr(self, key):
                continue
            if key == "contents":
                value = [QARFemaleContent.model_validate(v) for v in value]
                setattr(self, 'female_contents', value)
                setattr(self, 'contents', [v for v in value if v.check])
            elif key == "asr_features":
                value = [QARFemaleFeature.model_validate(v) for v in value]
                value = [v for v in value if v.check]
                setattr(self, 'asr_features', value)
            elif key == "status":
                setattr(self, 'status', '已发布')
            elif key in ["part_type", "part_name", "product_type", "part_no"]:
                setattr(self, key, value)
            else:
                if getattr(self, key):
                    continue
                setattr(self, key, value)
        return self


class QARUpdateStatus(BaseModel):
    status: Optional[str] = None


class QARStampType(BaseModel):
    type: str


class QARUpdate(QAR):
    contents: List[QARContent] = []
